// 1.2 字符串-C++ 中的 String 类
/**
 * C++ 提供了以下两种类型的字符串表示形式：
 *    C 风格字符串
 *    C++ 引入的 string 类类型
 * 
 * ------------------------
 * C++ 中的 String 类
 * C++ 标准库提供了 string 类类型，支持上述所有的操作，另外还增加了其他更多的功能。我们将学习 C++ 标准库中的这个类，现在让我们先来看看下面这个实例：
 * 现在您可能还无法透彻地理解这个实例，因为到目前为止我们还没有讨论类和对象。所以现在您可以只是粗略地看下这个实例，等理解了面向对象的概念之后再回头来理解这个实例。
 *    
*/

#include <iostream>
#include <cstring>

int main(void)
{
  std::string str1 = "RUNOBB";
  std::string str2 = "google";
  std::string str3;

  // 复制str1 => str3
  str3 = str1;
  std::cout << "str3 : " << str3 << std::endl; // "RUNOBB"

  // 拼接
  std::cout << "str1 + str2 : " << str1 + str2 << std::endl;               // "RUNOBBgoogle"
  std::cout << "str1 + \" \" + str2 : " << str1 + " " + str2 << std::endl; // "RUNOBB google"

  // 字符串的长度
  std::cout << "str1 size : " << str1.size() << std::endl; // 6

  // str1 != str2
  if (str1 == str2)
  {
    std::cout << "str1 == str2" << std::endl;
  }
  else
  {
    std::cout << "str1 != str2" << std::endl;
  }

  // str1 == str2
  if (str1 == str3)
  {
    std::cout << "str1 == str3" << std::endl;
  }
  else
  {
    std::cout << "str1 != str3" << std::endl;
  }

  // strcpy(str3, str1); // error: cannot convert 'std::__cxx11::string' {aka 'std::__cxx11::basic_string<char>'} to 'char*'

  // char str4[7];
  // strcpy(str4, str1); //  error: cannot convert 'std::__cxx11::string' {aka 'std::__cxx11::basic_string<char>'} to 'const char*'

  // strcpy(str4, (char *)str1);// error: invalid cast from type 'std::__cxx11::string' {aka 'std::__cxx11::basic_string<char>'} to type 'char*'  不存在从 "std::__cxx11::string" 到 "char *" 的适当转换函数C/C++

  // ----其实，从上面就可以看出，函数参数本来就要隐式类型转换，但报错了，就说明c++没提供 两种类型的转换方法

  // strlen(str3);

  std::cout << "字符串的自动"
               "拼接以及分隔符\\\
使用" << std::endl;

  std::cout << "----------一些string方法----------" << std::endl;

  std::string str5 = "test string";
  str5.append(" hhh");

  std::cout << "末尾追加 hhh: " << str5 << std::endl;

  std::cout << "字符串长度length: " << str5.length() << std::endl;

  str5.replace(11, 4, " HHH");
  std::cout << "\" hhh\"替换\" HHH\": " << str5 << std::endl;

  // std::size_t pos;
  // int pos = str5.find_first_of('H', 0);// 第二个参数是查询的起始位置，默认0
  int pos = str5.find_first_of('H');

  std::cout << "H在str5中第一次出现的位置是 : " << pos << std::endl;

  str5 += "__HHC";
  std::cout << "str5 : " << str5 << " length : " << str5.size() << std::endl; // test string HHH__HHC  20
  int s = str5.find_first_of("HHH");                                          // 从头向尾开始查, 返回查询到的子字符串第一个字符的索引

  int e = str5.find_last_of("HH"); // 第二个参数默认值end， 从尾向头， 查询出子字符串在字符串中最后一次出现的位置，返回查询到的子字符串最后一个字符的索引

  // test string HHH__HHC
  // 0                  19

  std::cout << " s : " << s << " e : " << e << std::endl;
  //  s: 12 e: 18

  std::cout << "substr取子字符串: " << str5.substr(s) << std::endl; // HHH_HHC substr 第二个参数是取几个字符，默认取剩余的部分即取到末尾索引

  pos = str5.find("HHH"); // 第二个参数开始查询位置
  std::cout << "find方法查找字符串: " << pos << std::endl;

  str5.replace(pos, 3, ""); // 替换为空字符串即删除
  std::cout << "截取字符串 : " << str5 << std::endl;

  str5.insert(pos, "HHH"); // 三参数写法、迭代器做参数写法 之后扩展

  std::cout << "插入字符串 : " << str5 << std::endl;

  std::cout << "sizeof(\"xxxxx\") : " << sizeof("xxxxx") << std::endl; // 6

  int arr[] = {1, 2, 3, 4, 5};
  char arr_s[] = {'1', '2', '3', '4', '5'};
  std::cout << "sizeof({1, 2, 3, 4, 5}) : " << sizeof arr << std::endl;              // 20 = sizeof(int) * 5
  std::cout << "sizeof({'1', '2', '3', '4', '5'}) : " << sizeof(arr_s) << std::endl; // 5 =  sizeof(char) * 5

  std::cout << "sizeof(char) : " << sizeof(char) << std::endl;

  printf("-----------end-------------\n");
  return 0;
}
